var _ = require('lodash')
var moment = require('moment')
var crypto = require('crypto')

/**
 * 返回错误响应体
 * @param msg 错误信息字符串，如果是字符串数组，则取第一条
 * @param code 错误代码，可为空
 * @returns {Object}
 */
exports.apiError = function (msg, code) {
  if (msg instanceof Array) msg = _.values(msg[0])[0]
  return {
    success: false,
    msg: msg || 'Unknown error',
    code: code
  }
}

/**
 * 返回正确响应体
 * @param data 数据对象，若是字符串，则赋值到msg上
 * @param code 错误代码，可为空
 * @returns {Object}
 */
exports.apiSuccess = function (data) {
  var obj = { success: true }
  if (typeof data === 'string') obj.msg = data
  else if (typeof data === 'object') obj = _.assign(obj, data)
  return obj
}

/**
 * 生成mongodb连接字符串
 * @param config 配置对象
 * @returns {String}
 */
exports.createConnStr = function (config) {
  var hosts = config.hosts instanceof Array
      ? config.hosts.join(',') : config.hosts
  var auth = config.username && config.password
      ? `${config.username}:${config.password}@` : ''
  var options = config.option instanceof Array
      ? config.option.join('&') : config.option ? config.option : ''
  return `mongodb://${auth}${hosts}/${config.name}?${options}`
}

/**
 * md5加密
 * @param str
 * @returns {String}
 */
exports.md5 = function (str) {
  return crypto.createHash('md5').update(str).digest('hex')
}

/**
 * 校验签名
 * @param params 参数对象（包含sign、timestamp等属性）
 * @param secret 密钥
 * @returns {Boolean}
 */
exports.checkSign = function (params, secret) {
  var sign = params.sign
  var _params = _.omit(params, ['sign'])
  var timestamp = _params.timestamp
  if (moment().format('X') - moment(timestamp, 'YYYYMMDDHHmmss').format('X') > 30) return false // 计算时否超时(30秒)
  var signPre = Object.keys(_params).sort().map((key) => `${key}=${_params[key]}`).join('') + secret
  var _sign = this.md5(signPre)
  return _sign === sign
}

/**
 * 生成签名
 * @param params 参数对象
 * @param secret 密钥
 * @returns {Object}
 */
exports.createSign = (params, secret) => {
  var _params = (typeof params === 'object') ? _.clone(params) : {}
  _params['timestamp'] = moment(new Date()).format('YYYYMMDDHHmmss')
  var signPre = Object.keys(_params).sort().map((key) => `${key}=${_params[key]}`).join('') + secret
  _params['sign'] = this.md5(signPre)
  return _params
}
